feat: Add wallet library#8417
Conversation
|
Caution MetaMask internal reviewing guidelines:
|
623f9af to
3fb60ee
Compare
45d013e to
6ec54b9
Compare
39b963d to
0d6028e
Compare
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Builds and tests pass. All lint issues are fixed except a handful that are deferred pending future changes. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Moderate risk due to new controller dependencies and changes to initialization wiring/typing that could affect runtime messaging and controller lifecycle. Test behavior now depends on external `INFURA_PROJECT_KEY` and mocked timers, which may introduce CI/environment sensitivity. > > **Overview** > **Stabilizes wallet builds/tests by wiring in missing controllers and config.** The wallet package now depends on additional controllers (accounts/approval/connectivity/network/remote feature flags/transaction) and updates TS project references accordingly. > > **Improves runtime/test ergonomics.** Jest loads a local `.env` (with `.env.example` added and `.env` gitignored), `Wallet` exposes stronger typed `messenger`/`state` and adds `destroy()` to clean up controller instances; tests are updated to require `INFURA_PROJECT_KEY`, use fake timers, and properly teardown the wallet. > > **Tightens initialization typing and controller wiring.** Adds `initialization/defaults.ts` for inferred `DefaultInstances`/`DefaultActions`/`DefaultEvents`, introduces `bindMessengerAction` to preserve action typings, and updates controller initializers (notably `TransactionController` and `RemoteFeatureFlagController`) to pass required options and bind messenger actions safely. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a652933. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com>
Anvil provides a local chain for the transaction test, and the remaining tests don't make real RPC calls (nock blocks outgoing network), so a real Infura key is no longer needed to run the test suite. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a test for `createSecretRecoveryPhrase` to cover the untested utility. Marks the defensive `return undefined` branch in `destroy()` as ignored (all real controllers have a destroy method). Lowers coverage thresholds from 100% to reflect code that is not yet reachable from the public API in this prototype stage (e.g. isOffline callback, encryptor factory bodies, ConnectivityController.init). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously a pretest lifecycle hook, which is not guaranteed to run depending on how CI invokes tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Silences foundryup output on success (prints on failure), extracts the install step into a named test:prepare script for discoverability, and adds a yarn.config.cjs exception since the wallet test script differs from the monorepo standard. Also updates the stale error message in anvil.ts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Yarn's built-in shell doesn't support the shell syntax needed to suppress foundryup output on success and print it on failure. Moving to a real bash script avoids Yarn shell quirks that may explain why the anvil binary download isn't running reliably in CI. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
mm-foundryup installs anvil to <cwd>/node_modules/.bin/anvil. If cwd isn't what we expect when the script runs (which may be why CI fails), anvil ends up somewhere neither getAnvilBinaryPath candidate matches. Explicitly cd to the package root and verify the expected file exists after install, with diagnostic output on failure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Node 18 does not expose globalThis.crypto by default, which causes the wallet package's tests to fail inside browser-passworder's generateSalt. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
## Summary - Add synchronous, per-property SQLite persistence to the wallet package using better-sqlite3 - Each controller state property with `persist: true` metadata gets its own row in a `kv` table (key format: `ControllerName.propertyName`) - Writes happen synchronously within the same call stack as `controller.update()` via `stateChanged` event subscriptions, eliminating data loss windows - Defaults to `:memory:` when no database path is provided ## Test plan - [ ] `yarn workspace @metamask/wallet exec jest --no-coverage --watchman=false src/persistence/` — 22 unit tests covering KeyValueStore CRUD, loadState grouping, persist filtering, StateDeriver application, patch-based diffing, unsubscribe, and multi-controller scenarios - [ ] `yarn workspace @metamask/wallet exec tsc --noEmit` — no new type errors - [ ] Integration test with file-backed DB: create Wallet with a file path, perform operations, create second Wallet from same path, verify state restoration 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Introduces a new persistence layer and changes wallet lifecycle/messenger semantics, plus adds a native dependency (`better-sqlite3`) that can affect build/install reliability across environments. > > **Overview** > Adds a new `persistence` subpath export that provides synchronous SQLite-backed state storage via `KeyValueStore`, plus `loadState` (reconstruct controller state from `Controller.prop` keys) and `subscribeToChanges` (persist only `persist`-flagged controller properties based on Immer patches and delete on removal). > > Updates `Wallet` construction/typing to accept optional preloaded `state`, exposes `controllerMetadata` for initialized controllers, switches messenger namespace to `Wallet`, and makes `destroy()` idempotent while publishing a new `Wallet:destroyed` event after best-effort controller teardown. > > Wires in the native `better-sqlite3` dependency (with LavaMoat allow-scripts), adds test/CI setup to install required binaries (`anvil` + `better-sqlite3` prebuild) and documents how to rebuild the native addon. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 772c1e6. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
d9daf4f to
88c6f09
Compare
There was a problem hiding this comment.
Should this persistence API be in this package? I don't expect this would be used in either client
There was a problem hiding this comment.
It shouldn't. We were planning to move that before attempting to merge this
Explanation
Feature branch. WIP.
Know limitations:
References
Checklist